package com.koron.order.common.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.koron.bean.query.PageQuery;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.common.core.business.common.service.CommonService;
import com.koron.common.core.business.common.service.SystemCommonService;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.StringUtils;
import com.koron.order.common.bean.base.OrderStatus;
import com.koron.order.common.bean.base.OrderType;
import com.koron.order.common.bean.convertor.OrderAllConvertor;
import com.koron.order.common.bean.po.OrderAllPo;
import com.koron.order.common.bean.po.OrderLocationPo;
import com.koron.order.common.bean.po.OrderWorkDeptPo;
import com.koron.order.common.bean.query.OrderAllQuery;
import com.koron.order.common.bean.query.OrderNoMergeQuery;
import com.koron.order.common.bean.vo.MonthTaskVo;
import com.koron.order.common.bean.vo.OrderAllConfirmVo;
import com.koron.order.common.bean.vo.OrderAllVo;
import com.koron.order.common.bean.vo.OrderNoMergeVo;
import com.koron.order.common.mapper.OrderAllMapper;
import com.koron.order.common.mapper.OrderNomergeMapper;
import com.koron.order.common.service.OrderAllService;
import com.koron.order.common.service.OrderLocationService;
import com.koron.order.common.service.OrderWorkDeptService;
import com.koron.order.common.tools.CommonCodeTools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * (OrderAll)表服务实现类
 *
 * @author zhouj
 * @since 2021-10-13 16:52:33
 */
@Slf4j
@Service("orderAllService")
public class OrderAllServiceImpl implements OrderAllService, CommonService {

    @Autowired
    OrderAllConvertor orderAllConvertor;

    @Autowired
    SystemCommonService systemCommonService;

    @Autowired
    OrderLocationService orderLocationService;

    @Autowired
    OrderWorkDeptService orderWorkDeptService;

    @Override
    @TaskAnnotation("queryById")
    public OrderAllPo queryById(SessionFactory factory, String id) {

        OrderAllMapper mapper = factory.getMapper(OrderAllMapper.class);

        return mapper.queryById(id);
    }

    @Override
    @TaskAnnotation("queryList")
    public List<OrderAllPo> queryList(SessionFactory factory, OrderAllQuery query) {

        OrderAllMapper mapper = factory.getMapper(OrderAllMapper.class);

        List<OrderAllPo> list = mapper.queryList(query);

        return list;
    }

    @Override
    @TaskAnnotation("queryDayTaskList")
    public Map<String, List<OrderAllPo>> queryDayTaskList(SessionFactory factory, OrderAllQuery query) {

        OrderAllMapper mapper = factory.getMapper(OrderAllMapper.class);
        EamUser eamUser = ThreadLocalContext.get();
        String deptId = eamUser.getDeptId();
        // 设备管理单位
        query.setDeptManage(deptId);

        //工单类型 没有则默认
        if (CollectionUtils.isEmpty(query.getOrderTypeList())) {
            query.setOrderTypeList(OrderType.getOrderTypeList());
        }

        //工单状态 没有则默认
        if (CollectionUtils.isEmpty(query.getStatusList())) {
            query.setStatusList(OrderStatus.allList);
        }

        //orgId 有值则需要查询该组织下的全部人员,设置进账号列表
        if (!StringUtils.isEmpty(query.getOrgId())) {
            //查询该组织下的人员账号列表
            List<String> list = systemCommonService.queryAccountListByOrgId(query.getOrgId());
            if (CollectionUtils.isNotEmpty(list)) {
                query.setAccountList(list);
            }
        }

        List<OrderAllPo> result1 = mapper.queryList(query);

        // 派工负责人
        OrderAllQuery orderAllQuery = new OrderAllQuery();
//        if (query.getCurrDate()!=null){
//            orderAllQuery.setCurrDate(query.getCurrDate());
//        }
        orderAllQuery.setUpdateBy(eamUser.getAccount());
        orderAllQuery.setStatusList(Arrays.asList(OrderStatus.WAIT_DISPATCH));
        orderAllQuery.setOrderTypeList(query.getOrderTypeList());
        List<OrderAllPo> result2 = mapper.queryList(orderAllQuery);

        List<OrderAllPo> list = Stream.of(result1,result2).flatMap(Collection::stream).distinct().collect(Collectors.toList());

        //实际查询  待审核状态只取试验工单类型,需要过滤掉缺陷工单的待审核状态的数据
        if (CollectionUtils.isNotEmpty(list)) {
            Iterator<OrderAllPo> it = list.iterator();
            while (it.hasNext()) {
                OrderAllPo next = it.next();
                if (StringUtils.equals(OrderStatus.WAIT_REVIEW, next.getStatus()) && StringUtils.equals(OrderType.DEFECT, next.getOrderType())) {
                    it.remove();
                }
            }
        }

        Map<String, List<OrderAllPo>> map = new HashMap() {
            {
                put("done", new ArrayList<OrderAllPo>());
                put("unDone", new ArrayList<OrderAllPo>());
                put("waitAccept", new ArrayList<OrderAllPo>());
                put("allTask", new ArrayList<OrderAllPo>());
            }
        };

        if (CollectionUtils.isEmpty(list)) {
            return map;
        }

        // 添加红绿灯展示
        list.forEach(p -> {
            String trafficLight = CommonCodeTools.calcTrafficLight(p.getFactEndTime(), p.getStartTime(), p.getEndTime(), p.getStatus());
            p.setTrafficLight(trafficLight);
        });

        map.put("allTask", list);

        for (OrderAllPo orderAllPo : list) {
            if (OrderStatus.isDoneList(orderAllPo.getStatus())) {
                List<OrderAllPo> done = map.getOrDefault("done", new ArrayList<>());
                done.add(orderAllPo);
                map.put("done", done);
            } else if (OrderStatus.isUnDoneList(orderAllPo.getStatus())) {
                List<OrderAllPo> unDone = map.getOrDefault("unDone", new ArrayList<>());
                unDone.add(orderAllPo);
                map.put("unDone", unDone);
            } else {
                //待验收  待审核(试验工单)
                List<OrderAllPo> waitAccept = map.getOrDefault("waitAccept", new ArrayList<>());
                waitAccept.add(orderAllPo);
                map.put("waitAccept", waitAccept);
            }
        }

        return map;
    }

    @Override
    @TaskAnnotation("queryPageList")
    public PageInfo<OrderAllVo> queryPageList(SessionFactory factory, OrderAllQuery query, PageQuery pageQuery) {
        if (!ObjectUtils.isEmpty(query.getMobile()) && query.getMobile()){
            query.setDeptManages(getCurrUserOrgIds());
        }
        PageHelper.startPage(pageQuery.getPage(), pageQuery.getPageSize(), pageQuery.getOrderBy(false));
        OrderAllMapper mapper = factory.getMapper(OrderAllMapper.class);

        List<OrderAllPo> list = mapper.queryList(query);
        PageInfo pageInfo = new PageInfo(list);

        List<OrderAllVo> voList = orderAllConvertor.poToVo(list);

        //单独查询一下 确认状态
        if (CollectionUtils.isNotEmpty(voList)) {
            List<String> ids = voList.stream().map(OrderAllPo::getId).collect(Collectors.toList());

            //1.1 项目确认进度
            List<OrderAllConfirmVo> orderAllConfirmVos = mapper.queryConfirmByIds(ids);
            Map<String, OrderAllConfirmVo> cond = new HashMap<>();
            if (CollectionUtils.isNotEmpty(orderAllConfirmVos)) {
                orderAllConfirmVos.forEach(p -> {
                    cond.put(p.getId(), p);
                });
            }
            voList.forEach(p -> {
                OrderAllConfirmVo orderAllConfirmVo = cond.get(p.getId());
                if (!Objects.isNull(orderAllConfirmVo)) {
                    p.setConfirm(orderAllConfirmVo.getConfirm());
                    p.setConfirmCount(orderAllConfirmVo.getConfirmCount());
                }
            });

            //1.2 工作地点
            List<OrderLocationPo> orderLocationPos = orderLocationService.queryByOrderIds(factory, ids);
            if (CollectionUtils.isNotEmpty(orderLocationPos)) {
                Map<String, List<OrderLocationPo>> map = orderLocationPos.stream().collect(Collectors.groupingBy(OrderLocationPo::getOrderId));
                voList.forEach(p->{
                    p.setOrderLocationList(map.getOrDefault(p.getId(),new ArrayList<>()));
                });
            }

            //1.3 作业单位
            List<OrderWorkDeptPo> orderWorkDeptPos = orderWorkDeptService.queryByOrderIds(factory, ids);
            if (CollectionUtils.isNotEmpty(orderWorkDeptPos)) {
                Map<String, List<OrderWorkDeptPo>> map = orderWorkDeptPos.stream().collect(Collectors.groupingBy(OrderWorkDeptPo::getOrderId));
                voList.forEach(p->{
                    p.setOrderWorkDeptPoList(map.getOrDefault(p.getId(),new ArrayList<>()));
                });
            }
        }
        pageInfo.setList(voList);
        return pageInfo;
    }

    @Override
    @TaskAnnotation("queryListNoMerge")
    public List<OrderNoMergeVo> queryListNoMerge(SessionFactory factory, OrderNoMergeQuery query) {

        OrderNomergeMapper mapper = factory.getMapper(OrderNomergeMapper.class);

        List<OrderNoMergeVo> list = mapper.queryList(query);

        return list;
    }

    @Override
    @TaskAnnotation("queryMonthTaskList")
    public List<MonthTaskVo> queryMonthTaskList(SessionFactory factory, OrderAllQuery query) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<MonthTaskVo> monthTaskVos = new ArrayList<>();

        Map<String, Integer> done_map = new HashMap<>();
        Map<String, Integer> unDone_map = new HashMap<>();
        Map<String, Integer> waitAccept_map = new HashMap<>();

        String currDate = query.getCurrDate();
        if (StringUtils.isEmpty(currDate)) {
            currDate = sdf.format(new Date());
            query.setCurrDate(currDate);
        }
        String substring = currDate.substring(0, 8);
        try {
            Date parse = sdf.parse(currDate);
            int daysOfMonth = getDaysOfMonth(parse);

            for (int i = 1; i <= daysOfMonth; i++) {
                MonthTaskVo monthTaskVo = new MonthTaskVo();
                monthTaskVos.add(new MonthTaskVo(substring + getDay(i)));
            }

            Calendar cal = Calendar.getInstance();
            cal.setTime(parse);
            cal.set(Calendar.DATE, 1);
            String month_first = sdf.format(cal.getTime());
            cal.add(Calendar.MONTH, 1);
            cal.set(Calendar.DATE, 1);
            cal.add(Calendar.DATE, -1);
            String month_end = sdf.format(cal.getTime());

            query.setCurrDate(null);
            query.setMonthFirst(month_first);
            query.setMonthEnd(month_end);

        } catch (ParseException e) {
            log.error(e.getMessage(), e);
            Assert.isTrue(false, "日期格式解析错误");
        }

        OrderAllMapper mapper = factory.getMapper(OrderAllMapper.class);

        if (CollectionUtils.isEmpty(query.getOrderTypeList())) {
            query.setOrderTypeList(OrderType.getOrderTypeList());
        }

        if (CollectionUtils.isEmpty(query.getStatusList())) {
            query.setStatusList(OrderStatus.allList);
        }

        //查出该月所有任务
        List<OrderAllPo> orderAllPoList = mapper.queryList(query);

        if (CollectionUtils.isEmpty(orderAllPoList)) {
            return monthTaskVos;
        }

        //对所有任务进行处理
        for (OrderAllPo orderAllPo : orderAllPoList) {

            String startTime = sdf.format(orderAllPo.getStartTime());
            String endTime = sdf.format(orderAllPo.getEndTime());

            String maxStartTime = maxStartTime(startTime, query.getMonthFirst());
            String minEndTime = minEndTime(endTime, query.getMonthEnd());

            List<String> days = getDays(maxStartTime, minEndTime);

            for (String day : days) {

                if (OrderStatus.isDoneList(orderAllPo.getStatus())) {
                    done_map.put(day, done_map.getOrDefault(day, 0) + 1);
                } else if (OrderStatus.isUnDoneList(orderAllPo.getStatus())) {
                    unDone_map.put(day, unDone_map.getOrDefault(day, 0) + 1);
                } else {
                    waitAccept_map.put(day, unDone_map.getOrDefault(day, 0) + 1);
                }
            }
        }

        //找到记录才赋值
        monthTaskVos.forEach(p -> {

            Integer integer = done_map.get(p.getDate());
            p.setDone(done_map.getOrDefault(p.getDate(), 0));
            p.setUndone(unDone_map.getOrDefault(p.getDate(), 0));
            p.setWaitAccept(waitAccept_map.getOrDefault(p.getDate(), 0));
            p.setNums(p.getDone() + p.getUndone() + p.getWaitAccept());

        });

        return monthTaskVos;
    }

    private String minEndTime(String endTime, String monthEnd) {
        return endTime.compareTo(monthEnd) <= 0 ? endTime : monthEnd;
    }

    private String maxStartTime(String startTime, String monthFirst) {

        return startTime.compareTo(monthFirst) >= 0 ? startTime : monthFirst;
    }

    /**
     * 获取两个日期之间的所有日期
     *
     * @param startTime 开始日期
     * @param endTime   结束日期
     * @return
     */
    public static List<String> getDays(String startTime, String endTime) {

        // 返回的日期集合
        List<String> days = new ArrayList<String>();

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date start = dateFormat.parse(startTime);
            Date end = dateFormat.parse(endTime);

            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(start);

            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(end);
            tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
            while (tempStart.before(tempEnd)) {
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }

        } catch (ParseException e) {
            log.error(e.getMessage(), e);
        }

        return days;
    }

    @Override
    @TaskAnnotation("queryPageListNoMerge")
    public PageInfo<OrderNoMergeVo> queryPageListNoMerge(SessionFactory factory, OrderNoMergeQuery query, PageQuery
            pageQuery) {

        PageHelper.startPage(pageQuery.getPage(), pageQuery.getPageSize(), pageQuery.getOrderBy());
        OrderNomergeMapper mapper = factory.getMapper(OrderNomergeMapper.class);

        //第一次分页查询
        List<OrderNoMergeVo> pageList = mapper.queryPageList(query);
        if (CollectionUtils.isNotEmpty(pageList)) {
            List<String> ids = pageList.stream().map(OrderNoMergeVo::getId).collect(Collectors.toList());
            //第二次根据条件查询
            query.setIds(ids);
            List<OrderNoMergeVo> list = mapper.queryList(query);

            //1.1 将项目负责人,工作成员及现场负责人设置进去
            Map<String, OrderNoMergeVo> map = new HashMap<>();
            list.forEach(p -> map.put(p.getId(), p));
            for (OrderNoMergeVo orderNoMergeVo : pageList) {
                orderNoMergeVo.setLeaderVo(map.get(orderNoMergeVo.getId()).getLeaderVo());
                orderNoMergeVo.setOrderDispatcherVoList(map.get(orderNoMergeVo.getId()).getOrderDispatcherVoList());
                orderNoMergeVo.setOrderLocationList(map.get(orderNoMergeVo.getId()).getOrderLocationList());
            }

            //1.2 工作地点
            List<OrderLocationPo> orderLocationPos = orderLocationService.queryByOrderIds(factory, ids);
            if (CollectionUtils.isNotEmpty(orderLocationPos)) {
                Map<String, List<OrderLocationPo>> cond1 = orderLocationPos.stream().collect(Collectors.groupingBy(OrderLocationPo::getOrderId));
                pageList.forEach(p->{
                    p.setOrderLocationList(cond1.getOrDefault(p.getId(),new ArrayList<>()));
                });
            }

            //1.3 作业单位
            List<OrderWorkDeptPo> orderWorkDeptPos = orderWorkDeptService.queryByOrderIds(factory, ids);
            if (CollectionUtils.isNotEmpty(orderWorkDeptPos)) {
                Map<String, List<OrderWorkDeptPo>> cond2 = orderWorkDeptPos.stream().collect(Collectors.groupingBy(OrderWorkDeptPo::getOrderId));
                pageList.forEach(p->{
                    p.setOrderWorkDeptPoList(cond2.getOrDefault(p.getId(),new ArrayList<>()));
                });
            }

            return new PageInfo(pageList);
        }

        return new PageInfo(new ArrayList());
    }

    public static int getDaysOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    public static String getDay(int i) {
        return i < 10 ? "0" + i : "" + i;
    }

}
